﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Xml.Linq;

namespace IBoLT.SettingWindows
{
	/// <summary>
	/// Логика взаимодействия для Labyrinth.xaml
	/// </summary>
	public partial class PerlinNoise : Window
	{
		// Тектура для предпросмотра
		private System.Drawing.Bitmap texture;

		public AForge.Imaging.Filters.Texturer filter;
		private AForge.Imaging.Textures.ITextureGenerator generator;
		public TextureSettings STexture;

		public PerlinNoise(System.Drawing.Bitmap sourcePreview, TextureSettings STexture)
		{
			this.STexture = STexture;

			InitializeComponent();
			
			// Добавляю обработчик к событиям в коде, т.к. для его работы необходимо создание формы
			sliderRings.ValueChanged += hPerlinNoisePreview;
			sliderXPeriod.ValueChanged += hPerlinNoisePreview;
			sliderYPeriod.ValueChanged += hPerlinNoisePreview;
			sliderLvlTexture.ValueChanged += hPerlinNoisePreview;
			sliderLvlFilter.ValueChanged += hPerlinNoisePreview;

			typeTexture.SelectionChanged += typeTexture_SelectionChanged;

			// Привязка команд к обработчикам //
			CommandBinding commBind = new CommandBinding(CommandsIBoLT.cPerlinNoiseGenerate, hPerlinNoiseGenerateEx); this.CommandBindings.Add(commBind);
			
			texture = sourcePreview;
			wPreview.Width = texture.Width;
			wPreview.Height = texture.Height;

			hPerlinNoisePreview(null, null);
		}

		// Обработчик изменения значений ползунков (предпросмотр)
		private void hPerlinNoisePreview(object sender, RoutedPropertyChangedEventArgs<double> e)
		{
			switch (typeTexture.SelectedIndex)
			{
				case 0:
					generator = new AForge.Imaging.Textures.WoodTexture(sliderRings.Value);
					break;
				case 1:
					generator = new AForge.Imaging.Textures.LabyrinthTexture();
					break;
				case 2:
					generator = new AForge.Imaging.Textures.MarbleTexture(sliderXPeriod.Value, sliderYPeriod.Value);
					break;
				case 3:
					generator = new AForge.Imaging.Textures.CloudsTexture();
					break;
				case 4:
					generator = new AForge.Imaging.Textures.TextileTexture();
					break;
			}

			filter = new AForge.Imaging.Filters.Texturer(generator,	sliderLvlFilter.Value, sliderLvlTexture.Value);
			wPreview.Source = SystemDrawingHelper.BitmapToBitmapImage(filter.Apply(texture));
		}

		// Обработчик кнопки "Генерировать"
		private void hPerlinNoiseGenerateEx(object sender, ExecutedRoutedEventArgs e)
		{
			switch (typeTexture.SelectedIndex)
			{
				case 0:
					STexture.Settings.Root.Add(new XElement("Генератор",
						new XAttribute("Название", "PerlinNoiseWood"),
						new XElement("Параметры",
							new XElement("Алгоритма",
								new XAttribute("Число_колец", sliderRings.Value)),
							new XElement("Наложения",
								new XAttribute("Исходная_текстура", sliderLvlTexture.Value),
								new XAttribute("Генериремая_текстура", sliderLvlFilter.Value)))));
					break;
				case 1:
					STexture.Settings.Root.Add(new XElement("Генератор",
						new XAttribute("Название", "PerlinNoiseLabyrinth"),
						new XElement("Параметры",
							new XElement("Наложения",
								new XAttribute("Исходная_текстура", sliderLvlTexture.Value),
								new XAttribute("Генериремая_текстура", sliderLvlFilter.Value)))));
					break;
				case 2:
					STexture.Settings.Root.Add(new XElement("Генератор",
						new XAttribute("Название", "PerlinNoiseMarble"),
						new XElement("Параметры",
							new XElement("Алгоритма",
								new XAttribute("Частота_по_X", sliderXPeriod.Value),
								new XAttribute("Частота_по_Y", sliderYPeriod.Value)),
							new XElement("Наложения",
								new XAttribute("Исходная_текстура", sliderLvlTexture.Value),
								new XAttribute("Генериремая_текстура", sliderLvlFilter.Value)))));
					break;
				case 3:
					STexture.Settings.Root.Add(new XElement("Генератор",
						new XAttribute("Название", "PerlinNoiseClouds"),
						new XElement("Параметры",
							new XElement("Наложения",
								new XAttribute("Исходная_текстура", sliderLvlTexture.Value),
								new XAttribute("Генериремая_текстура", sliderLvlFilter.Value)))));
					break;
				case 4:
					STexture.Settings.Root.Add(new XElement("Генератор",
						new XAttribute("Название", "PerlinNoiseTextile"),
						new XElement("Параметры",
							new XElement("Наложения",
								new XAttribute("Исходная_текстура", sliderLvlTexture.Value),
								new XAttribute("Генериремая_текстура", sliderLvlFilter.Value)))));
					break;
			}

			// Диалог успешен
			DialogResult = true;
		}

		// Обработчик выбора типа текстуры
		private void typeTexture_SelectionChanged(object sender, SelectionChangedEventArgs e)
		{
			if (typeTexture.SelectedIndex == 0)
			{
				grWoodS.Visibility = Visibility.Visible;
				grMarble.Visibility = Visibility.Hidden;
				hPerlinNoisePreview(null, null);
			}
			else if (typeTexture.SelectedIndex == 1 || typeTexture.SelectedIndex == 3 || typeTexture.SelectedIndex == 4)
			{
				grWoodS.Visibility = Visibility.Hidden;
				grMarble.Visibility = Visibility.Hidden;
				hPerlinNoisePreview(null, null);
			}
			else if (typeTexture.SelectedIndex == 2)
			{
				grWoodS.Visibility = Visibility.Hidden;
				grMarble.Visibility = Visibility.Visible;
				hPerlinNoisePreview(null, null);
			}
		}
	}
}
